/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * 
 * Project Name:assign-tracer
 * Create Time: 2016年2月24日 下午11:31:39
 */
package com.lenovo.lmrp.server.assigntracer.domain.workflow;

import java.util.Objects;

import com.lenovo.lmrp.api.model.entity.ProcessActivityPO;
import com.lenovo.lmrp.api.model.entity.TicketProcessPO;
import com.lenovo.lmrp.api.model.entity.TicketProcessPO.ProcessInstStatus;
import com.lenovo.lmrp.api.model.view.ChangedTicketVO;
import com.lenovo.sdc.framework.util.CommonUtil;
import com.lenovo.sdc.framework.util.exception.ErrorCode;
import com.lenovo.sdc.framework.util.exception.TraceableException;

/**
 * Wrap TicketProcess business logic, for example trigger workflow, stop workflow
 * @author wujin
 * @version v1.0
 */
public class TicketProcessBO {
    private IProcessService service;
    private TicketProcessPO ticketProcessPO;
    
    public TicketProcessBO(IProcessService service, TicketProcessPO ticketProcessPO) {
        this.service = service;
        this.ticketProcessPO = ticketProcessPO;
    }
    
    public void triggerWorkflow(ChangedTicketVO vo) {
        // we use event drive workflow then switch base on action
        // but these ation has relationship, we should check accept action of one activity
        
        ProcessActivityPO activityPO = ticketProcessPO.getCurrentActivity();
        if (containActivity(activityPO.getAcceptAction(), vo.getAction()))
            service.fireProcessInstance(ticketProcessPO, vo);
        else {
            String error = String.format("Illegal action [%s] for current workflow node [%s] in ticket [%s]", 
                vo.getAction(), ticketProcessPO.getActivityKey(), vo.getTicketid());
            throw new TraceableException(ErrorCode.COMM_PARAM_INVALID, error);
        }
    }
    
    /**
     * Obtain ticket process current workflow node
     * 
     * @return null means process end
     */
    public ProcessActivityPO getCurrentActivity() {
        if (ticketProcessPO.getStatus().equals(ProcessInstStatus.STOPED))
            return null;
        else if (ticketProcessPO.getStatus().equals(ProcessInstStatus.STARTED))
            return ticketProcessPO.getActivites().get(0);  //may throw null exception
        else
            return ticketProcessPO.getCurrentActivity();
    }
    /**
     * 获取当前流程的下一步操作
     * @return
     */
    public ProcessActivityPO getNextActivity() {
    	ProcessActivityPO currActivity = this.getCurrentActivity();
    	if(Objects.nonNull(currActivity)) {
    		for (ProcessActivityPO pa : ticketProcessPO.getActivites()) {
				if(pa.getSortForApp() == (currActivity.getSortForApp() + 1)) {
					return pa;
				}
			}
    	}
    	return null;
    }
    
    private boolean containActivity(String acceptActions, String action) {
        if (CommonUtil.isNullOrEmpty(acceptActions) || CommonUtil.isNullOrEmpty(action))
            return false;
        else {
            String[] acts = acceptActions.split("[\\,]");
            for (String act : acts) {
                if (act.equals(action))
                    return true;
            }
            
            return false;
        }
    }
}
